package com.sk.rpcAssistNetty.io.netty.server;

import com.sk.rpcAssistNetty.io.netty.RpcRequest;
import com.sk.rpcAssistNetty.io.netty.RpcResponse;
import com.sk.rpcAssistNetty.policy.ServiceBeanDefinitionRegistry;
import com.sk.rpcAssistNetty.util.ObjectUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * description：
 *
 * @author 孙文斌
 * @Date: 2021/3/18 10:40
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务端接收到了请求"+(RpcRequest) msg);
        RpcResponse response = new RpcResponse();
        RpcRequest request = null;
        Object result = null;
        try {
            request = (RpcRequest) msg;
            response.setRequestId(request.getRequestId());
            //反射调用本地服务
            result = invoke(request);
            if(result!=null){
                response.setSuccess(true);
                response.setResult(result);
            }else {
                response.setSuccess(false);
                response.setError("invoke server method error");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.setSuccess(false);
            response.setError(e.getMessage());
        }
        //返回结果
        System.out.println("服务端返回结果为："+response.toString());
        ctx.writeAndFlush(response);
    }

    //服务的调用（反射的方式）
    public static Object invoke(RpcRequest request) {
        try {
            //检查服务是否暴露
            ObjectUtil.checkNotNull(request.getClassName(), "className is null");
            ObjectUtil.checkNotNull(request.getMethodName(), "methodName is null");
            Object object = ObjectUtil.checkNotNull(ServiceBeanDefinitionRegistry.provideMap.get(request.getClassName()), "No corresponding execution class was found：" + request.getClassName());
            Method method = object.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
            ObjectUtil.checkNotNull(method, "No corresponding execution method was found：" + request.getMethodName());
            return method.invoke(object,request.getArguments());
        } catch (Exception e) {
            log.error("server invoke error,info:" + e);
        }
        return null;
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}
